# -*- coding: utf-8 -*-
# @Time       : 2019/7/28 上午8:00
# @Author     : Simon
# @Email      : 
# @File       : plugin.py
# @Software   : PyCharm
# @Description:
from LoggerWarpper import logger

from config import config
from db import getMidExposure, updYseOrderInfo, getYesOrderInfo, avgInfoList, avgEleInfoList, getOrderNum, \
    new_getOrderNum, getYesOrderList, setNewExposureNum0, formatInfoList, ShopBidding, ShopBiddingTarget, \
    updAllShopBiddingTarget, isSpecialTime, ShopMeituanInfo, ShopEleInfo, formatAdtAndSpt, deleteTodayTarget, \
    getELEinfo, getMTinfo, Session, updEleShopInfo, updShopMeituanInfo
from spider import ELESpider,MTSpider
import json,time,datetime
import traceback
import math

def IsInAdTime(shiptime,ad=False):
    '''
    判断是否在营业时间
    :param shiptime:
    :return:
    '''

    try:
        shipTimes = eval(shiptime)
    except:
        shipTimes =shiptime
    # if not shiptime and not ad:return True
    # if not shiptime and ad:return False

    for shiptime in shipTimes:
        starttime=shiptime.get("s")
        endtime =shiptime.get("e")
        if starttime and endtime:
            st = datetime.datetime.now().date().strftime("%Y-%m-%d") + ' ' + starttime
            st = datetime.datetime.strptime(st, '%Y-%m-%d %H:%M')

            et = datetime.datetime.now().date().strftime("%Y-%m-%d") + ' ' + endtime
            et = datetime.datetime.strptime(et, '%Y-%m-%d %H:%M')
            if datetime.datetime.now() > st and datetime.datetime.now() < et:
                return True

    return  False

def new_dateRange(ad_s,ad_e,mins,immediate):

    today = None
    if immediate == 1:
        today = datetime.datetime.now().date().strftime("%Y-%m-%d")
    else:
        today = (datetime.datetime.now() + datetime.timedelta(days=1)).strftime("%Y-%m-%d")
    dates = []
    if datetime.datetime.strptime(today + " " + ad_s + ":00", "%Y-%m-%d %H:%M:%S") + datetime.timedelta(minutes = 30) > datetime.datetime.strptime(today + " " + ad_e + ":00", "%Y-%m-%d %H:%M:%S"):
        min1 = int(ad_s.split(":")[1])
        min2 = int(ad_e.split(":")[1])
        if 0 <= min1 < min2 < 30 or 30 <= min1 < min2 < 60 :
            dates.append(today + " " + ad_s + ":00")
            dates.append(today + " " + ad_e + ":00")
            return dates
    #30分钟或者15分钟
    ad_s = today + " " + ad_s + ":00"
    ad_e = today + " " + ad_e + ":00"

    dates.append(ad_s)
    ad_e_str = ad_e

    ad_s = datetime.datetime.strptime(ad_s, "%Y-%m-%d %H:%M:%S")
    ad_s_time = ad_s

    gap = []
    ad_s = ad_s.strftime("%Y-%m-%d %H:00:00")

    s = datetime.datetime.strptime(ad_s, "%Y-%m-%d %H:%M:%S")
    e = s + datetime.timedelta(hours=1)
    gap.append(s.strftime("%Y-%m-%d %H:%M:%S"))
    stime = s + datetime.timedelta(minutes=mins)
    while stime <= e:
        gap.append(stime.strftime("%Y-%m-%d %H:%M:%S"))
        stime = stime + datetime.timedelta(minutes=mins)

    need = None
    for st in gap:
        if st > ad_s_time.strftime("%Y-%m-%d %H:%M:%S"):
            need = st
            break

    dates.append(need)

    ad_s = datetime.datetime.strptime(need, "%Y-%m-%d %H:%M:%S")
    ad_e = datetime.datetime.strptime(ad_e, "%Y-%m-%d %H:%M:%S")

    ad_time = ad_s + datetime.timedelta(minutes=mins)
    while ad_time <= ad_e:
        dates.append(ad_time.strftime("%Y-%m-%d %H:%M:%S"))
        ad_time = ad_time + datetime.timedelta(minutes=mins)

    if not ad_e_str in dates:
        dates.append(ad_e_str)
    return dates


def dateRange(beginDate, endDate):
    dates = []
    beginDatestr=(datetime.datetime.now().date()+datetime.timedelta(days=0)).strftime("%Y-%m-%d")
    beginDatestr=beginDatestr+' '+beginDate+":00"
    endDatestr = (datetime.datetime.now().date()+datetime.timedelta(days=0)).strftime("%Y-%m-%d")
    endDatestr = endDatestr + ' ' + endDate+":00"
    date = beginDatestr
    while date <= endDatestr:
        dates.append(date)
        date = datetime.datetime.strptime(date, '%Y-%m-%d %H:%M:%S') + datetime.timedelta(hours=1)
        date = date.strftime("%Y-%m-%d %H:00:00")
        # date=dt
    lt=time.strptime(endDatestr, "%Y-%m-%d %H:%M:%S")
    if lt[4] != 00:
        dates.append(endDatestr)
    return dates

def dataPrepare4setTarget(account,adTime,shopType,targetExposure,budget,immediate):
    '''准备爬虫信息'''
    shopInfo = None
    shopId = 0
    if shopType == 2:
        shopInfo = getELEinfo(account)
        shopId = shopInfo.get("id")
    elif shopType == 1:
        shopInfo = getMTinfo(account)
        shopId = shopInfo.get("id")

    specialtime = shopInfo.get("specialtime")
    '''获取店铺基本信息'''
    today = None
    if immediate == 1:
        today = datetime.datetime.now().date().strftime("%Y-%m-%d")
    else:
        today = (datetime.datetime.now() + datetime.timedelta(days=1)).strftime("%Y-%m-%d")
    mins = 30
    totalOrderNum = 0
    orderList = None

    #获取单，并订格式化为时间对应订单量格式
    updTime = shopInfo.get("updatetime")
    idleExposureRate = shopInfo.get("idleExposureRate")
    allExposureRate = shopInfo.get("allExposureRate")
    if updTime < today + " 00:00:00":
        infoList = getYesOrderInfo(account)
        orderList = [0 for i in range(0, int(60 / mins) * 24)]
        for t in infoList:
            if t and t[0]:
                t = eval(t[0])
                if len(t) == int(60 / mins) * 24:
                    for i in range(int(60 / mins) * 24):
                        orderList[i] += t[i]

    else:
        orderList = shopInfo.get("percent")





    orderList = formatInfoList(orderList, mins)

    ##获取ads_order
    ads_order = []
    if adTime != '[]':
        try:
            adTime = eval(adTime)
        except:
            adTime = adTime
        if not adTime:
            return
        for ad in adTime:
            if not ad: continue
            ad_s = ad['s']
            ad_e = ad['e']
            ads = (new_dateRange(ad_s, ad_e, mins,immediate))
            for i in range(1, len(ads)):
                ads_order.append([ads[i - 1], ads[i], 0, ad.get("p", 1)])
    for l in orderList:
        orderNum = l.get("orderNum", 0)
        ordertime = today + " " + l.get("date") + ":00"
        for k in range(0, len(ads_order)):
            beginStamp = int(time.mktime(time.strptime(ads_order[k][0], '%Y-%m-%d %H:%M:%S')))
            try:
                orderStampTime = int(time.mktime(time.strptime(ordertime, '%Y-%m-%d %H:%M:%S')))
            except:
                orderStampTime = int(time.mktime(time.strptime(today + " 23:59:59", '%Y-%m-%d %H:%M:%S')))
            if beginStamp >= (orderStampTime - mins * 60) and ads_order[k][1] <= ordertime:
                ads_order[k][2] = math.ceil(new_getOrderNum(ads_order[k][0], ads_order[k][1], orderNum, mins * 60))
                if ads_order[k][2] == 0:
                    ads_order[k][2] = 1
                #
    for i in range(0, len(ads_order)):
        #   先判断是不是忙时， 忙时的曝光量除以1.3
        totalOrderNum += ads_order[i][2]

    '''封装数据返回'''
    data = {
            "account" : account,
            "specialtime" : specialtime,
            "totalOrderNum" : totalOrderNum,
            "budget" : int(float(budget)),
            "mins" : mins,
            "ads_order" : ads_order,
            "targetExposure" : int(targetExposure),
            "shopId":shopId,
            "idleExposureRate" : idleExposureRate,
            "allExposureRate" : allExposureRate,
            }
    return data

def getLastBidding(shopid,today,type):
    '''
    获取补偿曝光量
    :return:
    '''
    try:
        session = Session()
        shopBidding =session.query(ShopBidding).filter(ShopBidding.shopid==shopid, ShopBidding.biddingTime >today, ShopBidding.shoptype==type,).order_by(ShopBidding.id.desc()).first()
        session.close()
        return shopBidding
    except:
        logger.warning(traceback.format_exc())
def getNewAdTime(adTime,ct,where):
    if ct < adTime[0].get('s') and where == 0:
        return []
    elif ct < adTime[0].get('s') and where == 1:
        return adTime
    elif ct > adTime[-1].get('e'):
        return []
    if where == 2:
        return adTime
    newAdTime = []
    flag = 0
    for ad in adTime:
        start = ad.get('s')
        end = ad.get('e')
        if ct > start and ct < end:
            if where == 0:
                ad['e'] = ct
            else:
                ad['s'] = ct
            newAdTime.append(ad)
            flag = 1
        else:
            if where == 0 and flag == 0:
                newAdTime.append(ad)
            elif where == 1 and flag == 1:
                newAdTime.append(ad)
    return newAdTime


def setTargetexposurePer4Web(data,type,nextExposureRate = 1):

    '''获取数据'''
    if not data:
        return
    ads_order = data.get("ads_order")
    totalOrderNum = data.get("totalOrderNum")
    targetExposure = data.get("targetExposure")
    account = data.get("account")
    shopId = data.get("shopId")
    budget = data.get("budget")
    specialtime = data.get("specialtime")
    idleExposureRate = data.get("idleExposureRate")

    if idleExposureRate:
        idleExposureRate = float(idleExposureRate)
    else:
        idleExposureRate = 1.45


    showCount = 0
    budgetstart = 0



    #无法生成计划
    if targetExposure < 0:
        return

    targetExposure = targetExposure * nextExposureRate
    index = 0
    all_plans = []
    #第一条计划标志为1，设置完后改为0
    for a in ads_order:  # 根据昨日订单量比例进行推广时间段的订单量分布
        orderNum = a[2]
        try:
            per = float(orderNum) / float(totalOrderNum)
        except:
            per = 0
        tarExposureHour = int(float(targetExposure) * per * float(a[3]))
        perBudget = budget * per * float(a[3])


        if isSpecialTime(specialtime, a[0]) == 0:
            tarExposureHour = int(tarExposureHour * idleExposureRate)

        timeStamp = int(time.mktime(time.strptime(a[0], '%Y-%m-%d %H:%M:%S')))
        stopTimeStamp = int(time.mktime(time.strptime(a[1], '%Y-%m-%d %H:%M:%S')))
        addbianliang = timeStamp
        # 循环让时间增加，输出预期预期的曝光量
        while (addbianliang < stopTimeStamp):
            getTarExposure = getMidExposure(showCount, showCount + tarExposureHour, addbianliang - timeStamp, stopTimeStamp - timeStamp)
            getTarExposure = int(getTarExposure)
            targetBudget = getMidExposure(budgetstart, budgetstart + perBudget, addbianliang - timeStamp, stopTimeStamp - timeStamp)
            targetBudget = round(targetBudget,2)
            time_local = time.localtime(addbianliang)
            the_time = time.strftime("%Y-%m-%d %H:%M:%S", time_local)
            if  len(all_plans) > 0:
                if the_time!=all_plans[-1].exposureTime:
                    all_plans.append(ShopBiddingTarget(
                        account=account,
                        exposureNum=getTarExposure,
                        budget=targetBudget,
                        exposureTime=the_time,
                        type=type,
                        shopid=shopId
                    ))
            else:
                all_plans.append(ShopBiddingTarget(
                    account=account,
                    exposureNum=getTarExposure,
                    budget=targetBudget,
                    exposureTime=the_time,
                    type=type,
                    shopid=shopId
                ))
            addbianliang += 60 * 2
        if index < len(ads_order) - 1 and ads_order[index][1] != ads_order[index + 1][0]:
            if  len(all_plans)>0 and ads_order[index][1]!=all_plans[-1].exposureTime:
                all_plans.append(ShopBiddingTarget(
                    account=account,
                    exposureNum=showCount + tarExposureHour,
                    budget=budgetstart + perBudget,
                    exposureTime=ads_order[index][1],
                    type=type,
                    shopid=shopId
                ))
        showCount += tarExposureHour
        budgetstart += perBudget
        lastTimeStamp = stopTimeStamp
        index += 1
    time_local = time.localtime(lastTimeStamp)
    the_time = time.strftime("%Y-%m-%d %H:%M:%S", time_local)
    if len(all_plans) > 0 and the_time != all_plans[-1].exposureTime:
        all_plans.append(ShopBiddingTarget(
            account=account,
            exposureNum=showCount,
            budget=budgetstart,
            exposureTime=the_time,
            type=type,
            shopid=shopId
        ))
    updAllShopBiddingTarget(all_plans)



def newSetTargetexposurePer4Web(data,type, idleExposureRate, updExposureRate ,nextExposureRate):

    '''获取数据'''
    if not data:
        return
    ads_order = data.get("ads_order")
    totalOrderNum = data.get("totalOrderNum")
    targetExposure = data.get("targetExposure")
    account = data.get("account")
    shopId = data.get("shopId")
    budget = data.get("budget")
    specialtime = data.get("specialtime")


    showCount = 0
    budgetstart = 0

    currentTimeStamp = int(time.time())

    #无法生成计划
    if targetExposure < 0:
        return
    targetExposure = targetExposure * nextExposureRate
    index = 0
    all_plans = []
    #第一条计划标志为1，设置完后改为0
    for a in ads_order:  # 根据昨日订单量比例进行推广时间段的订单量分布
        orderNum = a[2]
        try:
            per = float(orderNum) / float(totalOrderNum)
        except:
            per = 0
        tarExposureHour = int(float(targetExposure) * per * float(a[3]))

        if isSpecialTime(specialtime, a[0]) == 0:
            tarExposureHour = int(tarExposureHour * idleExposureRate)

        perBudget = budget * per * float(a[3])
        timeStamp = int(time.mktime(time.strptime(a[0], '%Y-%m-%d %H:%M:%S')))
        stopTimeStamp = int(time.mktime(time.strptime(a[1], '%Y-%m-%d %H:%M:%S')))
        addbianliang = timeStamp
        # 循环让时间增加，输出预期预期的曝光量
        flag = 0
        while (addbianliang < stopTimeStamp):

            if addbianliang > currentTimeStamp and flag == 0:
                flag = 1
                tarExposureHour = int(tarExposureHour * updExposureRate)

            getTarExposure = getMidExposure(showCount, showCount + tarExposureHour, addbianliang - timeStamp, stopTimeStamp - timeStamp)
            getTarExposure = int(getTarExposure)
            targetBudget = getMidExposure(budgetstart, budgetstart + perBudget, addbianliang - timeStamp, stopTimeStamp - timeStamp)
            targetBudget = round(targetBudget,2)
            time_local = time.localtime(addbianliang)
            the_time = time.strftime("%Y-%m-%d %H:%M:%S", time_local)
            if  len(all_plans) > 0:
                if the_time!=all_plans[-1].exposureTime:
                    all_plans.append(ShopBiddingTarget(
                        account=account,
                        exposureNum=getTarExposure,
                        budget=targetBudget,
                        exposureTime=the_time,
                        type=type,
                        shopid=shopId
                    ))
            else:
                all_plans.append(ShopBiddingTarget(
                    account=account,
                    exposureNum=getTarExposure,
                    budget=targetBudget,
                    exposureTime=the_time,
                    type=type,
                    shopid=shopId
                ))
            addbianliang += 60 * 2
        if index < len(ads_order) - 1 and ads_order[index][1] != ads_order[index + 1][0]:
            if  len(all_plans)>0 and ads_order[index][1]!=all_plans[-1].exposureTime:
                all_plans.append(ShopBiddingTarget(
                    account=account,
                    exposureNum=showCount + tarExposureHour,
                    budget=budgetstart + perBudget,
                    exposureTime=ads_order[index][1],
                    type=type,
                    shopid=shopId
                ))
        showCount += tarExposureHour
        budgetstart += perBudget
        lastTimeStamp = stopTimeStamp
        index += 1
    time_local = time.localtime(lastTimeStamp)
    the_time = time.strftime("%Y-%m-%d %H:%M:%S", time_local)
    if len(all_plans) > 0 and the_time != all_plans[-1].exposureTime:
        all_plans.append(ShopBiddingTarget(
            account=account,
            exposureNum=showCount,
            budget=budgetstart,
            exposureTime=the_time,
            type=type,
            shopid=shopId
        ))
    updAllShopBiddingTarget(all_plans)


def geteleShopBussinessStatus(cookie):
    '''
    获取饿了么店铺状态信息
    :return:
    '''
    try:
        ele=ELESpider(cookie)
        shopstatus = ele.getShopStatus()
        shopid = ele.reqcookie['eleshopid']
        account = ele.reqcookie['account']
        result = shopstatus.get("result",[])[0]
        detail = result.get("detail",{})

        shipTime = ''
        shiptimeDesc = ''
        for shiptime in detail.get("businessHours", []):
            stime = (shiptime.get("startTime", '') + '-' + shiptime.get("endTime", ''))
            shiptimeDesc += (stime + ',')
        shipTime = shiptimeDesc[:-1]
        if not shipTime:
            shipTime = "00:00-23:59"

        status=detail.get("nowIsInBusinessHour")
        if status:
            status=1
        else:
            status=0

        session = Session()
        shop = session.query(ShopEleInfo).filter(ShopEleInfo.account == account).first()
        session.close()
        db_shipping_time = shop.shipTime
        if not db_shipping_time == shipTime:
            # 重新计算推广时间，并重新生成竞价计划
            formatTimeResult = formatAdtAndSpt(shipTime)
            adTimeList = formatTimeResult.get("date", {}).get("adTimeResult", [])
            shipTimeList = formatTimeResult.get("date", {}).get("shipTimeResult", [])
            adTime = str(adTimeList)
            # shipTime = ''
            # for st in shipTimeList:
            #     shipTime += st
            #     shipTime += ','
            # shipTime = shipTime[:-1]
            updEleShopInfo(**dict(eleId=shopid, eleisenable=1, eleshiptime=shipTime, shopstatus=status, account=account,
                                  eleadtime=adTime))
            try:
                nextExposureRate = getNextExposureRate(account, 2)
                deleteTodayTarget(account, 1)
                data = dataPrepare4setTarget(account, adTime, 2, shop.targetExposure, shop.budget, 1)
                setTargetexposurePer4Web(data, 2, nextExposureRate)
            except:
                logger.warning(traceback.format_exc())

        return (status, shipTime)
    except:
        logger.warning(traceback.format_exc())
        return 1000

def getTimeIndex(t):
    h = t.split(":")[0]
    m = t.split(":")[1]
    index = int(h)*2 - 1
    if int(m) == 30:
        index += 1
    return index



def getmtShopBussinessStatus(account, cookie):
    '''
    获取店铺状态信息
    :return:
    '''
    status=0
    try:
        mt = MTSpider(cookie)
        shopstatus = mt.getShopStatus(None)
        wmPoiId = mt.reqcookie['wmPoiId']
        status = shopstatus.get("status",0)
        #商店营业时间范围
        shipTime = shopstatus.get("shippingTimeDesc")
        substatus = shopstatus.get("subStatus",1000)
        if substatus:
            status=0

        session = Session()
        shop = session.query(ShopMeituanInfo).filter(ShopMeituanInfo.account == account).first()
        session.close()
        db_shipping_time = shop.shipTime
        if not db_shipping_time == shipTime:
            # 重新计算推广时间，并重新生成竞价计划
            formatTimeResult = formatAdtAndSpt(shipTime)
            adTimeList = formatTimeResult.get("date", {}).get("adTimeResult", [])
            shipTimeList = formatTimeResult.get("date", {}).get("shipTimeResult", [])
            adTime = str(adTimeList)
            # shipTime = ''
            # for st in shipTimeList:
            #     shipTime += st
            #     shipTime += ','
            # shipTime = shipTime[:-1]
            updShopMeituanInfo(
                **dict(mtId=wmPoiId, shopstatus=status, mtisenable=1, mtshiptime=shipTime, mtadtime=adTime))
            nextExposureRate = getNextExposureRate(account, 1)
            deleteTodayTarget(account, 1)
            data = dataPrepare4setTarget(account, adTime, 1, shop.targetExposure, shop.budget, 1)
            setTargetexposurePer4Web(data, 1, nextExposureRate)


        return status
    except:
        logger.warning(traceback.format_exc())
        return 1000

def getNextExposureRate(account,shopType):
    session = Session()
    if shopType == 1:
        plan = session.query(ShopMeituanInfo.plan).filter(ShopMeituanInfo.account == account).scalar()
    else:
        plan = session.query(ShopEleInfo.plan).filter(ShopEleInfo.account == account).scalar()

    if plan:
        plan = eval(plan)
        if plan.get("nextExposureRate",None):
            return float(plan.get("nextExposureRate"))
        else:
            return 1
    else:
        return 1